package server;

import java.util.List;
import java.util.Observable;
import java.util.Observer;

import protocol.ClientProtocol;
import protocol.ServerProtocol;

import spel.Bord;
import spel.Knikker;
import spel.Spel;
import spel.Speler;
import spel.Zet;
/**
 * Een Implementatie van de interface Spel.Speler die gebruik maakt van een netwerkverbinding om zijn zetten op te halen.
 * @author Tim en Stef
 *
 */
public class NetwerkSpeler implements Speler, Observer {
	ClientHandler c;
	Zet ontvangenZet = null;
	Zet partialZet;
	
	/**
	 * Creeerd een netwerkspeler die zijn zetten via de ClientHandler doorgeeft
	 * @param c de clienthandler die naar de Client communiceerd
	 */
	public NetwerkSpeler(ClientHandler c) {
		this.c = c;
		c.addObserver(this);
		partialZet = null;
	}
	
	/**
	 * Vraag de ClientHandler om een zet.
	 */
	@Override
	public Zet doeZet(Bord b) {
		
		synchronized (this) {
			if (ontvangenZet == null) {
				try {
					wait();
				} catch (InterruptedException e) {

				}
			}
			Zet tempzet = ontvangenZet;
			ontvangenZet = null;
			return tempzet;

		}

	}


	@Override
	/**
	 * @return De naam van de speler
	 */
	public String getNaam() {
		// TODO Auto-generated method stub
		return c.getName();
	}

	@Override
	/**
	 * Verwerkt de veranderingen in het spel en stuurt deze eventueel door naar de client.
	 * En verwerkt berichten van de clienthandler om zetten te doen.
	 */
	public void update(Observable arg0, Object arg1) {
		if (arg0 instanceof ClientHandler) {
			if (arg1 instanceof String) {
				String[] tokens = ((String) arg1).split(""
						+ ServerProtocol.DELIM);

				if (tokens[0].equals(ClientProtocol.DO_MOVE) && ontvangenZet == null) {
					Zet z = new Zet(null, Integer.parseInt(tokens[1]),
							Integer.parseInt(tokens[2]),
							Integer.parseInt(tokens[3]), null);
					if (tokens[4].equals("+")) {
						z.richting = Zet.Richting.Rechts;
					} else {
						z.richting = Zet.Richting.Links;
					}
					synchronized (this) {
						ontvangenZet = z;
						this.notify();
					}
				}
			}
		}

		if (arg0 instanceof Spel) {
			if (arg1 instanceof Zet) {
				Zet z = (Zet) (arg1);
				if (z.richting == null) {
					partialZet = z;
				} else {
					partialZet.index = z.index;
					partialZet.richting = z.richting;
					String richtingstring = "";
					if (partialZet.richting == Zet.Richting.Rechts) {
						richtingstring = "+";
					} else {
						richtingstring = "-";
					}
					c.sendCommand(ServerProtocol.MOVE, new String[] {
							"" + partialZet.x,
							"" + partialZet.y, "" + partialZet.index, richtingstring });
					partialZet = null;
				}
			}
			if (arg1 instanceof List<?>) {
				List<Speler> winnaars = (List<Speler>) arg1;
				String winnaarstring[] = new String[winnaars.size()];
				for (int i = 0; i < winnaars.size(); i++) {
					winnaarstring[i] = winnaars.get(i).getNaam();
				}
				c.sendCommand(ServerProtocol.GAME_OVER, winnaarstring);

			}
			if(arg1 instanceof Knikker){
				c.sendCommand(ServerProtocol.NEXT_MOVE, new String[] { ((Knikker) arg1).getSpeler().getNaam() });
			}
		}

	}

}
